import permisions from './permission/index'
// #ifdef APP-PLUS
import permision from "@/utils/permissionCheck/permission.js"
// #endif
import { appConfig } from '@/config/index.js'
import { packagedUploadFile } from '@/utils/upload-tool'
/**
 * 日期格式化函数
 * @param date 日期对象
 * @param format 日期格式，默认为 YYYY-MM-DD HH:mm:ss
 */
export const formatDate = (date: Date, format = 'YYYY-MM-DD HH:mm:ss') => {
  // 获取年月日时分秒，通过 padStart 补 0
  const year = String(date.getFullYear())
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')

  // 返回格式化后的结果
  return format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hours)
    .replace('mm', minutes)
    .replace('ss', seconds)
}

// 数据转dict格式
export const data2Dict = (array: any) => {
  if (array == undefined) return []
  return array.map((item: any) => {
    return {
      value: isNaN(item.value) ? item.value : +item.value,
      label: item.name,
      disabled: item.isEnabled != 1,
      desc: item.desc,
    }
  })
}

// 工具函数 内容增加 unit 单位 默认 “元”
export function unitVal(val: any, unit: any = '元') {
  if (val || val === 0) {
    return val + ' ' + unit
  } else {
    return '-'
  }
}

/**
 * 将数值格式化为字符串，可选择是否添加千分位分隔符
 * @param val 待格式化的数值，可以是任何类型，但只有数值类型会被格式化
 * @param thousandth 是否添加千分位分隔符，默认为 false
 * @returns 格式化后的字符串
 */
export function formatNumber(val: any, thousandth = false) {
  let formatedStr = ''
  // 传入 null 或 undefined 时，返回 '0'
  if (val === null || val === undefined) {
    formatedStr = '0'
  }
  // 当传入的值为有效数值时，进行格式化
  if (isValid(val)) {
    // 将数值格式化为保留两位小数的字符串
    const number = val.toFixed(2)
    // 根据 thousandth 参数决定是否添加千分位分隔符
    if (thousandth) {
      // 添加千分位分隔符
      formatedStr = String(number).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
    } else {
      // 不添加千分位分隔符
      formatedStr = String(number)
    }
  }

  return formatedStr
}

// rpx转px
export const rpxToPx = (rpx: any) => {
  const screenWidth = uni.getSystemInfoSync().screenWidth
  return (screenWidth * Number.parseInt(rpx)) / 750
}

// px转rpx
export const pxToRpx = (px: any) => {
  const screenWidth = uni.getSystemInfoSync().screenWidth
  return (750 * Number.parseInt(px)) / screenWidth
}

// 带有权限的 chooseImage
export const chooseImageWidthPermission = (config = {}) => {
  const system = uni.getSystemInfoSync()
  if (system.osName == 'android') {
    return new Promise((resolve) => {
      permision.premissionCheck("CAMERA_EXTERNAL_STORAGE").then((result1)=>{
        console.log('result1', result1)
        if(result1 == 1) {
          uni.chooseImage({
            count: 1,
            sizeType: ['compressed'], //可以指定是原图还是压缩图，默认二者都有
            sourceType: ['camera', 'album'],
            ...config,
            success: (res) => {
              console.log(res)
              resolve(res)
            },
          })
        }
      })
    })
  }
  if (system.osName == 'ios') {
    return new Promise((resolve) => {
      uni.chooseImage({
        count: 1,
        sizeType: ['compressed'], //可以指定是原图还是压缩图，默认二者都有
        sourceType: ['camera', 'album'],
        ...config,
        success: (res) => {
          console.log(res)
          resolve(res)
        },
      })
    })
  }
}
// 上传文件
export const uploadFile = (imgPath: any) => {
  return new Promise((resolve) => {
    permision.premissionCheck("CAMERA_EXTERNAL_STORAGE").then((result1)=>{
      console.log('result1', result1)
      if(result1 == 1) {
        packagedUploadFile({
          filePath: imgPath,
          success: (res) => {
            const _data = JSON.parse(res.data)
            if (_data.code == 200) {
              resolve(_data.result[0])
            } else {
              uni.showToast({
                title: _data.resultMsg ? _data.resultMsg : '网络异常,请稍后再试',
                icon: 'none',
              })
            }
          },
          fail: (err) => {
            uni.showToast({
              title: '网络异常,请稍后再试',
              icon: 'none',
            })
          },
          complete: () => {
            uni.removeSavedFile({
              filePath: imgPath,
            })
          },
        })
      }
    })
  })
}
// 判断是否录入
// 0 被认为是有效输入 '' 被认为是无效输入
export function isValid(val: any) {
  return !!val || (typeof val == 'number' && val === 0)
}
// 深度克隆
export function cloneDeep(val: any) {
  return JSON.parse(JSON.stringify(val))
}
// 小数求和
export function decimalAddition(x = 0, y = 0) {
  const sum = (Number(x) + Number(y)).toFixed(3)
  return Math.round(+sum * 100) / 100
}
// 小数求差
export function decimalSubtract(x = 0, y = 0) {
  const sum = (x - y).toFixed(3)
  return Math.round(+sum * 100) / 100
}
// 序列化对象
export function serializeUrlParams(obj) {
  let str = ''
  for (const i in obj) {
    if (obj[i] == undefined) {
      continue
    }
    str += i + '=' + obj[i] + '&'
  }
  return str.replace(/&$/g, '')
}
// 拨打电话
export function dialPhone(phoneNumber: any) {

  const system = uni.getSystemInfoSync()
  if (phoneNumber) {
    // 手机号被加密
    if (phoneNumber.indexOf('*') >= 0) {
      uni.showToast({
        title: '手机号格式有误，暂无法拨打',
        icon: 'none',
      })
    } else {
      if (system.osName == 'android') {
        permision.premissionCheck("CALL_PHONE").then((result1)=>{
          console.log('result1', result1)
          if(result1 == 1) {
            uni.makePhoneCall({
              phoneNumber: phoneNumber,
            })
          }
        })
      }
      if (system.osName == 'ios') {
        // ios未处理权限
        uni.makePhoneCall({
          phoneNumber: phoneNumber,
        })
      }
    }
  }
}

// 节流函数
// export function throttle(fn: Function, wait: number) {
//   let pre = Date.now()
//   return function () {
//     const context = this
//     const args = arguments
//     const now = Date.now()
//     if (now - pre >= wait) {
//       fn.apply(context, args)
//       pre = Date.now()
//     }
//   }
// }

export function throttle(func: Function, delay: number) {
  let lastCall = 0
  let timeoutId: any = null
  let lastArgs: any = null

  return function () {
    const now = new Date().getTime()
    lastArgs = arguments

    if (now - lastCall < delay) {
      if (timeoutId) {
        clearTimeout(timeoutId)
      }

      timeoutId = setTimeout(() => {
        lastCall = now
        func.apply(this, lastArgs)
      }, delay)
    } else {
      lastCall = now
      func.apply(this, arguments)
    }
  }
}
// 长按复制
export function copyText(text: any) {
  // 设置系统剪贴板的内容
  uni.setClipboardData({
    data: text,
    success: () => {
      uni.showToast({
        title: '已复制',
        icon: 'none',
      })
    },
  })
}
// 获取 city 名字
// 由于高德地图逆经纬度查询详细信息时，遇到直辖市和省直辖县，返回的city会是 []，正常情况下返回 'xxx'
// 此处进行处理，为 city 补充上值
export const getAppLocationCity = (option) => {
  // 如果 city 是字符串，直接返回city
  if (option.city && typeof option.city === 'string') {
    return option.city;
  }
  // 如果省份以市结尾，为直辖市，返回省份
  if (option.province.endsWith('市')) {
    return option.province;
  }
  // 否则为省直辖县
  return option.district;
}
// 根据经纬度逆解析地址信息
export const getLocation2Address = (location) => {
  return new Promise((resolve) => {
    uni.request({
      url: 'https://restapi.amap.com/v3/geocode/regeo',
      data: {
        key: 'eeca91fd2e3b6dd5e084414659eae404',
        location: `${location.longitude},${location.latitude}`,
      },
      timeout: 6000,
      success(res) {
        const data = res.data
        const regeocode = data?.regeocode || {}
        // 更新 globalData > location
        const locationS = {
          ...regeocode.addressComponent,
          address: regeocode.formatted_address,
          longitude: location.longitude,
          latitude: location.latitude,
          city: getAppLocationCity(regeocode.addressComponent),
        }
        resolve(locationS)
      },
      fail(error) {
        console.log(error)
      },
    })
  })
}
/**
 * 编码参数以便URL传输。
 *
 * 该函数将任意类型的值编码为URL兼容的格式。
 * 特别地，它会将数组类型转换为JSON字符串后再进行编码，以确保数组结构在传输过程中保持不变。
 *
 * @param value - 需要编码的任意类型的值。这可以是字符串、数字、数组等。
 * @returns 返回输入值的URL编码字符串表示。
 */
function encodeParam(value: any) {
  if (Array.isArray(value)) {
    // 将数组转换为JSON字符串并进行URL编码
    return JSON.stringify(value)
  }
  // 直接对非数组值进行URL编码
  return value
}
/**
 * 将一个对象的属性转换为查询参数字符串
 *
 * 此函数遍历给定对象的所有可枚举属性，将它们转换为URL查询参数的形式
 * 如果属性值未定义，则该属性不会被包含在返回的查询字符串中
 *
 * @param obj 要转换为查询参数的对象
 * @param targetArray 可选的数组，转换后的查询参数将被添加到这个数组中如果未提供，则创建一个新的数组
 * @returns 返回组装好的查询字符串如果没有任何查询参数，则返回空字符串
 */
export function setQueryParams(obj: any, targetArray?: any) {
  // 初始化查询参数数组，如果提供了targetArray，则使用它，否则创建一个新的数组
  const params = targetArray || []

  // 遍历对象的所有可枚举属性
  for (const key in obj) {
    // 检查对象是否拥有该属性且属性值不是undefined
    if (obj.hasOwnProperty(key) && obj[key] !== undefined) {
      // 将属性转换为查询参数的形式，并添加到params数组中
      params.push(`${key}=${encodeParam(obj[key])}`)
    }
  }

  // 根据params数组的长度决定返回的查询字符串如果数组为空，则返回空字符串
  return params.length > 0 ? `?${params.join('&')}` : ''
}
/**
 * 获取URL参数
 * @param value
 * @returns
 */
export function evalQueryParam(value: string) {
  if (!value) {
    console.warn('Input value is empty or null')
    return null
  }

  try {
    const decodeValue = decodeURIComponent(value)
    return JSON.parse(decodeValue)
  } catch (error) {
    if (error instanceof URIError) {
      console.error('Invalid URI encoding:', error)
    } else if (error instanceof SyntaxError) {
      console.error('Invalid JSON format:', error)
    } else {
      console.error('Unexpected error:', error)
    }
    return null
  }
}
